﻿using CefSharp;
using CefSharp.WinForms;
using FictionsDownload.Enums;
using FictionsDownload.Events;
using Zzw;
using FictionsDownload.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace FictionsDownload.BLL.CefSharp
{
    public class CefSharpQidian : CefSharpBase, ICefSharp
    {
        #region 单例初始化
        private CefSharpQidian():base("http://www.qidian.com")
        {
            EventInit();
        }
        private static CefSharpQidian Instance { get; set; }
        private static readonly object lockRoot = new object();
        /// <summary>
        /// 初始化实例
        /// </summary>
        public static CefSharpQidian GetIntance
        {
            get
            {
                if (Instance == null)
                {
                    lock (lockRoot)
                    {
                        if (Instance == null)
                        {
                            Instance = new CefSharpQidian();
                        }
                    }
                }
                return Instance;
            }
        }
        #endregion
        #region 公共属性和事件
        /// <summary>
        /// 有新的消息需要添加（事件声明）
        /// </summary>
        public new event AddMessageEventHandler AddMessage;
        #endregion
        /// <summary>
        /// 追加事件的实现
        /// </summary>
        private void EventInit()
        {
            //web_Auto其他
            //web_Auto.RequestHandler = new RequestHandler_new(web_Auto.RequestHandler);//获取任意 资源的关键处。
        }


        /// <summary>
        /// 如果没有登录弹窗，就JS弹出
        /// </summary>
        private async Task<bool> PopLoginWindow()
        {
            if (!IsPopLoginWindow())
            {
                this.Html = "";
                var frame = WebBrowser.GetMainFrame();
                await frame.EvaluateScriptAsync("$(\"#login-btn\").click();");
                this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "登录弹窗还未弹出，点击主界面登陆按钮"));
            }
            for (int i = 0; i < 25; i++)
            {
                if (this.Html.IsNoNullOrEmpty())
                {
                    this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "网页已经加载完毕，开始判断登录窗口"));
                    if (IsPopLoginWindow())
                    {
                        this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "登陆弹窗已经弹出，开始登录"));
                        return true;
                    }
                    else
                    {
                        this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "登陆弹窗未弹出，返回失败"));
                        return false;
                    }
                }
                await Task.Delay(1000);
            }
            this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "主界面刷新25秒超时"));
            return false;
        }
        /// <summary>
        /// 判断登陆窗口是否弹出
        /// </summary>
        /// <returns></returns>
        private bool IsPopLoginWindow()
        {
            Regex reg = new Regex("<div class=\"qdlogin-wrap\">");
            Match match = reg.Match(Html);
            if (match.Success)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 开始登录帐号
        /// </summary>
        public override async Task<bool> LoginAccount()
        {
            if (await PopLoginWindow())
            {
                this.Html = "";
                var frames = WebBrowser.GetBrowser().GetFrameIdentifiers();
                var frameLogin = WebBrowser.GetBrowser().GetFrame(frames[1]);
                await frameLogin.EvaluateScriptAsync("$(\"#username\").val('17005056555');");
                await frameLogin.EvaluateScriptAsync("$(\"#password\").val('Zhang!0402');");
                await frameLogin.EvaluateScriptAsync("$(\".login-common-wrap .login-button\").click();");
                this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "输入帐号密码登录"));
                for (int i = 0; i < 25; i++)
                {
                    if (this.Html.IsNoNullOrEmpty())
                    {
                        if (WebBrowser.GetBrowser().GetFrameIdentifiers().Count != 1)
                        {
                            while (WebBrowser.GetBrowser().GetFrameIdentifiers().Count != 1)
                            {
                                this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "等待人工通过验证码校验"));
                                await Task.Delay(5000);
                            }
                            Html = await WebBrowser.GetSourceAsync();
                            IsLogin(Html);
                        }
                        if (UserName.IsNoNullOrEmpty())
                        {
                            this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "页面刷新完成，帐号成功登录"));
                            return true;
                        }
                        else
                        {
                            this.AddMessage?.Invoke(this, new AddMessageEventArgs(MessageTypeEnum.添加, "页面刷新完成，帐号登录失败"));
                            return false;
                        }
                    }
                    await Task.Delay(1000);
                }
            }
            return false;
        }
        private delegate void TaskDelegate(Task<JavascriptResponse> javascriptResponse);
        /// <summary>
        /// 委托处理：JS任务执行结果
        /// </summary>
        /// <param name="javascriptResponse"></param>
        private void EvaluateScriptAsync(Task<JavascriptResponse> javascriptResponse)
        {
            ////外线程调用
            //if (InvokeRequired)
            //{
            //    Invoke(new TaskDelegate(EvaluateScriptAsync), javascriptResponse);
            //    return;
            //}
            string EvaluateJavaScriptResult = null;
            javascriptResponse.ContinueWith(t =>
            {
                if (!t.IsFaulted)
                {
                    var response = t.Result;
                    EvaluateJavaScriptResult = response.Success ? (response.Result?.ToString()) : response.Message;
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
            if (EvaluateJavaScriptResult != null)
            {

            }
            return;
        }

        /// <summary>
        /// 检查是否登录
        /// </summary>
        /// <param name="html"></param>
        private string IsLogin(string html = null)
        {
            html = html ?? this.Html;
            if (UserName.IsNoNull())
            {
                return UserName;
            }
            else if(html.IsNull())
            {
                return null;
            }
            Regex reg = new Regex("<a class=\"black\" id=\"user-name\" href=\"//me.qidian.com\" target=\"_blank\" data-eid=\"qd_A08\">(.*?)</a>");
            Match match = reg.Match(html);
            if (match.Success)
            {
                string name = match.Groups[1].Value;
                if (name.IsNoNullOrEmpty())
                {
                    UserName = name;
                    return name;
                }
            }
            return null;
        }
        /// <summary>
        /// 跳转到指定网页
        /// </summary>
        /// <returns></returns>
        public override async Task<string> LoadUrlAsync(string url)
        {
            this.Html = "";
            WebBrowser.Load(url);
            for (int i = 1; i < 25; i++)
            {
                if (CurrentWebUrl.Equals(url) && Html.IsNoNullOrEmpty())
                {
                    break;
                }
                await Task.Delay(1000);
            }
            return Html;
        }
        /// <summary>
        /// 帐号是否登录（异步）
        /// </summary>
        /// <returns></returns>
        public override async Task<bool> LoginNameAsync()
        {
            if (IsLogin().IsNull())
            {
                this.Html = "";
                WebBrowser.GetBrowser().Reload();
            }
            for (int i = 1; i < 25; i++)
            {
                if (IsLogin().IsNoNull())
                {
                    return true;
                }
                else if (this.Html.IsNoNullOrEmpty())
                {
                    break;
                }
                await Task.Delay(1000);
            }
            return false;
        }
    }
}
